/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tresenraya;

/**
 *
 * @author Helena
 */

import static utilidades.constantes.*;

public class JugadorAutomatico extends Jugador {
    int profundidadMax;
    private int tipoDeMovimiento;
    private int iOrigen;
    private int jOrigen;
    private int iDestino;
    private int jDestino;

    public JugadorAutomatico(int profundidadMaxima)
    {
        this.profundidadMax = profundidadMaxima;
    }

    public void realizarJugada()
    {
        DecoradorPosicion decoradorDePosicionActual = new DecoradorPosicion(getPosicion());
        alfaBeta(decoradorDePosicionActual, MENOS_INFINITO, MAS_INFINITO, 0);

        //Ejecuta el movimiento del sucesor elegido
        decoradorDePosicionActual.ejecutarMovimiento();
        tipoDeMovimiento = decoradorDePosicionActual.getTipoMovimiento();
        iOrigen = decoradorDePosicionActual.getIOrigen();
        jOrigen = decoradorDePosicionActual.getJOrigen();
        iDestino = decoradorDePosicionActual.getIDestino();
        jDestino = decoradorDePosicionActual.getJDestino();
    }

    int alfaBeta(DecoradorPosicion posicionDecorada, int alfa, int beta, int profundidad)
    {
        if (posicionDecorada.getPosicion().hayTresEnRaya(getAdversario()))
        {
            posicionDecorada.setValor(MENOS_INFINITO);
            return MENOS_INFINITO;
        }
        else if (posicionDecorada.getPosicion().hayTresEnRaya(this))
        {
            posicionDecorada.setValor(MAS_INFINITO);
            return MAS_INFINITO;
        }
        else if (profundidad >= profundidadMax)
        {
            int valor = posicionDecorada.getPosicion().lineasDominadas(this) - posicionDecorada.getPosicion().lineasDominadas(this.getAdversario());
            posicionDecorada.setValor(valor);
            return valor;
        }
        else if (profundidad % 2 == 0) //NUDO MÁX
        {
            DecoradorPosicion sucesorMaximo = null;
            int alfaMaxima = MENOS_INFINITO;
            IteradorPosiciones iterador = new IteradorPosiciones(posicionDecorada);

            int nIteracion = 1;
            while (iterador.haySiguiente() && alfa < beta)
            {
                DecoradorPosicion sucesor = iterador.obtenerSiguiente();
                alfa = alfaBeta(sucesor, alfaMaxima, beta, profundidad+1);
                if (alfaMaxima < alfa || nIteracion == 1)
                {
                    alfaMaxima = alfa;
                    sucesorMaximo = sucesor;
                }
                nIteracion++;
            }

            if (sucesorMaximo == null) //si no hay sucesores, se procede igual que si se hubiera llegado a la profundidad máxima
            {
                int valor = posicionDecorada.getPosicion().lineasDominadas(this) - posicionDecorada.getPosicion().lineasDominadas(this.getAdversario());
                posicionDecorada.setValor(valor);
                return valor;
            }
            else
            {
                posicionDecorada.setValor(alfaMaxima);
                if (profundidad == 0) //el movimiento a realizar finalmente es el del sucesor máximo
                {
                    posicionDecorada.setMovimiento(sucesorMaximo);
                }
                return alfaMaxima;
            }
        }
        else  //NUDO MÍN
        {
            DecoradorPosicion sucesorMinimo = null;
            int betaMinima = MAS_INFINITO;
            IteradorPosiciones iterador = new IteradorPosiciones(posicionDecorada);

            int nIteracion = 1;
            while (iterador.haySiguiente() && alfa < beta)
            {
                DecoradorPosicion sucesor = iterador.obtenerSiguiente();
                beta = alfaBeta(sucesor, alfa, betaMinima, profundidad+1);
                if (betaMinima > beta || nIteracion == 1)
                {
                    betaMinima = beta;
                    sucesorMinimo = sucesor;
                }
                nIteracion++;
            }

            if (sucesorMinimo == null)
            {
                int valor = posicionDecorada.getPosicion().lineasDominadas(this) - posicionDecorada.getPosicion().lineasDominadas(this.getAdversario());
                posicionDecorada.setValor(valor);
                return valor;
            }
            else
            {
                posicionDecorada.setValor(betaMinima);
                return betaMinima;
            }
        }
    }

    public int obtenerTurno()
    {
        return 0;
    }

    boolean isDeseoTerminar()
    {
        return true;
    }

    /**
     * @return the tipoDeMovimiento
     */
    public int getTipoDeMovimiento() {
        return tipoDeMovimiento;
    }

    /**
     * @return the iOrigen
     */
    public int getIOrigen() {
        return iOrigen;
    }

    /**
     * @return the jOrigen
     */
    public int getJOrigen() {
        return jOrigen;
    }

    /**
     * @return the iDestino
     */
    public int getIDestino() {
        return iDestino;
    }

    /**
     * @return the jDestino
     */
    public int getJDestino() {
        return jDestino;
    }

}